﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using App1AppHandler;
using System.Timers;
using Reborn_WorldServer;
using System.Drawing;
using Reborn_WorldServer.App1AppHandler.Spells.Interfaces;

namespace Reborn_Server.App1AppHandler
{
    public class Spell_Ignite : Buff, IInstantCast
    {
        //Ignite base total damage = 280 Damage    12 Seconds Total
        private int BaseFireDamage = 46;  
        private int FireTicksStart = 6;




        //Necrosis base total damage = 220 Damage   14 Seconds Total (Level 3)
        private int BaseUnholyDamage = 31;
        private int UnholyTicksStart = 7;

        //Necrosis rank 2   376 Damage  20 Seconds (Level 13)
        private int Rank2BaseUnholyDamage = 47;
        private int Rank2UnholyTicksStart = 8;

        //Necrosis Rank 3 (495) (Level 21)
        private int Rank3BaseUnholyDamage = 55;
        private int Rank3UnholyTicksStart = 9;




        //Ice rank 1  228 damage 12 Seconds (Level 9)
        private int BaseIceDamage = 38;
        private int IceTicksStart = 6;

        //Ice rank 2 (400) Level 21
        private int Rank2IceDamage = 50;
        private int Rank2IceTicksStart = 8;




        //Ment Rank 1 182 Damage 14 Seconds (Level 5)
        private int BaseMentDamage = 26;
        private int MentTicksStart = 7;

        //Ment Rank 2 385 Damage     (Level 22)
        private int Rank2BaseMentDamage = 55;
        private int Rank2MentTicksStart = 7;




        //Holy is just DOT Heal 480 healing  24 Seconds (not counting bonuses)
        private int BaseHolyDamage = 40;
        private int HolyTicksStart = 12;

        //Rank 2   780 Damage 
        private int Rank2BaseHolyDamage = 60;
        private int Rank2HolyTicksStart = 13;


        private int BaseDotDamage = 0;
        private int CalcDotDamage = 0;

        public Spell_Ignite() 
        {
            spellTimer.Interval = 2000;

            minutesLeft = -2;
        }

        public override bool hasCustomTarget(SpellIcon sIcon)
        {
            if (sIcon.Skill == "Holy")
                return true;

            return false;
        }

        private List<Point> hiddenList;
        private CreatureBase choosenTarget;

        public override bool hasValidTarget(SpellIcon sIcon, Creature creature, List<Point> hiddenList)
        {
            this.hiddenList = hiddenList;

            List<CreatureBase> targetCreatures = new List<CreatureBase>();
            foreach (MapItem mapitem in creature.currentMapItem.mapItemsWithin4)
            {
                foreach (CreatureBase creatureBase in mapitem.CreaturesBases)
                {
                    if (creatureBase.Faction == creature.Faction && creatureBase.HP <= creatureBase.MaxHP / 2 &&
                        creature.buffManager.GetBuffByStackType(sIcon.StackType) == null)
                    {
                        targetCreatures.Add(creatureBase);
                    }
                }
            }

            int damagedAmount = 0;
            foreach (CreatureBase cb in targetCreatures)
            {
                if (CreatureAI.isHidden(cb.MapX, cb.MapY, hiddenList) == false)
                {
                    int damageValue = cb.MaxHP - cb.HP;
                    if (choosenTarget == null || damageValue > damagedAmount)
                    {
                        choosenTarget = cb;
                        damagedAmount = damageValue;
                    }
                }
            }

            if (choosenTarget == null)
                return false;
            else
                return true;
        }


        private int getTicksByBySkill(string skill)
        {
            switch (skill)
            {
                case "Fire":
                    return FireTicksStart;

                case "Unholy":
                    //Necrosis
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2UnholyTicksStart;
                    else if (spellIcon.Name.IndexOf("Rank 3") > -1)
                        return Rank3UnholyTicksStart;
                    else
                        return UnholyTicksStart;

                case "Holy":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2HolyTicksStart;
                    else
                        return HolyTicksStart;

                case "Ice":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2IceTicksStart;
                    else
                        return IceTicksStart;

                case "Mentality":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2MentTicksStart;
                    else
                        return MentTicksStart;
            }
            return 0;
        }
        private int getBaseBySkill(string skill)
        {
            switch (skill)
            {
                case "Fire":
                    return BaseFireDamage;
                case "Unholy":
                    //Necrosis
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2BaseUnholyDamage;
                    else if (spellIcon.Name.IndexOf("Rank 3") > -1)
                        return Rank3BaseUnholyDamage;
                    else
                        return BaseUnholyDamage;
                case "Holy":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2BaseHolyDamage;
                    else
                        return BaseHolyDamage; 
                case "Ice":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2IceDamage;
                    else
                        return BaseIceDamage;
                case "Mentality":
                    if (spellIcon.Name.IndexOf("Rank 2") > -1)
                        return Rank2BaseMentDamage;
                    else
                        return BaseMentDamage;
            }
            return 0;
        }

        public override void Resume(CreatureBase targetCreatureBase, SpellIcon _spellIcon, int timeRemaining, int castLevel, int castCharacterID, int castInt, int castWis, int optionalValue, string xmlData)
        {
            spellIcon = _spellIcon;

            if (_spellIcon.Skill == "Holy")
                minutesLeft = 1;

            BaseDotDamage = getBaseBySkill(_spellIcon.Skill);
            ticksLeft = getTicksByBySkill(_spellIcon.Skill);

            int DotAmount = BaseDotDamage * ticksLeft;
            
            if (_spellIcon.Skill != "Holy")
            {
                DotAmount = SkillManager.AdjustForCombat(castLevel, DotAmount, castInt);
                DotAmount = targetCreatureBase.CalculateGetSpellDamagePerResists(DotAmount, base.spellIcon.Skill);
            }
            else
                DotAmount = SkillManager.AdjustForCombat(castLevel, DotAmount, castWis);

            CalcDotDamage = DotAmount / ticksLeft;

            ticksLeft = timeRemaining;
            base.Resume(targetCreatureBase, _spellIcon, timeRemaining, castLevel, castCharacterID, castInt, castWis, optionalValue, xmlData);

            spellTimer.Start();
        }

        public void Cast(CreatureBase myCreatureBase, int CastLevel, long CreatureGUID)
        {
            //If its a creature custom cast, replace the targets ID
            if (choosenTarget != null)
                CreatureGUID = choosenTarget.CreatureID;

            List<MapItem> MapItemsWithin12;
            if (base.InitializeCast(myCreatureBase, CastLevel, CreatureGUID, true, out MapItemsWithin12) == false)
                return;

            if (spellIcon.Skill == "Holy")
                minutesLeft = 1;

            BaseDotDamage = getBaseBySkill(spellIcon.Skill);
            ticksLeft = getTicksByBySkill(spellIcon.Skill);

            int DotAmount = BaseDotDamage * ticksLeft;

            if (spellIcon.Skill != "Holy")
            {
                DotAmount = SkillManager.AdjustForCombat(CastLevel, DotAmount, myCreatureBase.IntelligenceTotal);
                DotAmount = TargetCreatureBase.CalculateGetSpellDamagePerResists(DotAmount, base.spellIcon.Skill);
            }
            else
                DotAmount = SkillManager.AdjustForCombat(CastLevel, DotAmount, myCreatureBase.WisdomTotal);

            CalcDotDamage = DotAmount / ticksLeft;

            foreach (MapItem mapitem in MapItemsWithin12)
            {
                foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                {
                    if (creaturebase is Character)
                    {
                        Character character = (Character)creaturebase;
                        if (spellIcon.Skill == "Fire" || spellIcon.Skill == "Mentality")
                            character.PlaySound("FireBolt", TargetCreatureBase.MapX, TargetCreatureBase.MapY);
                        else if (spellIcon.Skill == "Unholy" || spellIcon.Skill == "Ice")
                            character.PlaySound("Necrosis", TargetCreatureBase.MapX, TargetCreatureBase.MapY);
                        else if (spellIcon.Skill == "Holy")
                            character.PlaySound("Heal", TargetCreatureBase.MapX, TargetCreatureBase.MapY);
                    }
                }
            }

            TargetCreatureBase.buffManager.UpdateBuffs();

            spellTimer.Start();
        }
        protected override void SpellTimer_Expired(object source, ElapsedEventArgs e)
        {
            LockItem lockitem = TargetCreatureBase.GameHandler.GetLockItem(TargetCreatureBase.MapID, TargetCreatureBase.Instance);

            lock (lockitem.LockObj)
            {
                //This buff has been removed, do nothing (this can occur if the buff gets overwritten exactly when this timer fires)
                if (TargetCreatureBase.buffManager.hasBuff(this.SpellID) == false)
                    return;

                if (TargetCreatureBase.HP < 1)
                {
                    RemoveSpell(true, false);
                    return;
                }

                //Map CurrentMap = TargetCreatureBase.GameHandler.GetMap(TargetCreatureBase.MapID, TargetCreatureBase.Instance);
                //List<MapItem> MapItemsWithin8 = new List<MapItem>();
                List<Character> CharactersWithin8 = TargetCreatureBase.currentMapItem.getCharactersWithin8();
                //MapItem CurrentMapItem = null;
                //foreach (MapItem mapitem in CurrentMap.MapItems)
                //{
                //    if (Math.Abs(mapitem.MapX - TargetCreatureBase.MapX) <= 8 && Math.Abs(mapitem.MapY - TargetCreatureBase.MapY) <= 8)
                //    {
                //        MapItemsWithin8.Add(mapitem);
                //        foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                //        {
                //            if (creaturebase is Character)
                //                CharactersWithin8.Add((Character)creaturebase);
                //        }
                //    }
                //    if (mapitem.MapX == TargetCreatureBase.MapX && mapitem.MapY == TargetCreatureBase.MapY)
                //        CurrentMapItem = mapitem;
                //}

                int absorbedDamage = 0;
                if (spellIcon.Skill != "Holy")
                    TargetCreatureBase.InflictSpellDamage(CalcDotDamage, CastingCharacterID, CastingCreatureGUID, spellIcon.Skill, out absorbedDamage);
                else
                    TargetCreatureBase.HP = TargetCreatureBase.HP + CalcDotDamage;

                TargetCreatureBase.Update_Character();

                int actualDamage = CalcDotDamage - absorbedDamage;

                string targetMessageText = "";
                string casterMessageText = "";
                if (spellIcon.Skill == "Fire")
                {
                    //Dont send this message if CastingCharacterID && TargetCreatureBase are the same creature
                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        casterMessageText = TargetCreatureBase.Name + " burns" + " (" + actualDamage.ToString() + ")";

                    targetMessageText = "You are burning! (" + actualDamage.ToString() + ")";
                }
                else if (spellIcon.Skill == "Unholy")
                {
                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        casterMessageText = TargetCreatureBase.Name + "'s skin withers" + " (" + actualDamage.ToString() + ")";

                    targetMessageText = "You are withering! (" + actualDamage.ToString() + ")";
                }
                else if (spellIcon.Skill == "Holy")
                {
                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        casterMessageText = "You heal " + TargetCreatureBase.Name + " (" + actualDamage.ToString() + ")";

                    targetMessageText = "Your wounds mend! (" + actualDamage.ToString() + ")";
                }
                else if (spellIcon.Skill == "Ice")
                {
                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        casterMessageText = "You freeze " + TargetCreatureBase.Name + " (" + actualDamage.ToString() + ")";

                    targetMessageText = "You are freezing! (" + actualDamage.ToString() + ")";
                }
                else if (spellIcon.Skill == "Mentality")
                {
                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        casterMessageText = TargetCreatureBase.Name + "'s mind begins to melt. (" + actualDamage.ToString() + ")";

                    targetMessageText = "Your mind is melting! (" + actualDamage.ToString() + ")";
                }

                if (absorbedDamage != 0)
                {
                    if (casterMessageText != "")
                        casterMessageText = casterMessageText + " ABSORBED " + absorbedDamage.ToString();
                    if (targetMessageText != "")
                        targetMessageText = targetMessageText + " ABSORBED " + absorbedDamage.ToString();
                }
                if (casterMessageText != "")
                    Managers.GameHandler.TrySendMessage(CastingCharacterID, casterMessageText, "spelldamage");
                if (targetMessageText != "")
                    TargetCreatureBase.SendMessage(targetMessageText, "spelldamaged");

                if (TargetCreatureBase.HP < 1)
                {
                    //if (!(TargetCreatureBase is Character))
                    //    CurrentMapItem.CreaturesBases.Remove(TargetCreatureBase);

                    TargetCreatureBase.SendMessage("You have been slain!", "slain");

                    if (!(TargetCreatureBase is Character && TargetCreatureBase.ID == CastingCharacterID))
                        Managers.GameHandler.TrySendMessage(CastingCharacterID, "You have slain " + TargetCreatureBase.Name + "!", "slay");

                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.AddMapItem(TargetCreatureBase.currentMapItem);
                    }

                    //This spell killed the creature so this buff has already been removed, do nothing.
                    return;
                }
                else
                {
                    foreach (Character character in CharactersWithin8)
                    {
                        if (Math.Abs(character.MapX - TargetCreatureBase.MapX) <= 4 && Math.Abs(character.MapY - TargetCreatureBase.MapY) <= 4)
                            character.UpdateCreatureBaseHp(TargetCreatureBase);
                    }
                }
                if (ticksLeft > 0)
                {
                    ticksLeft--;
                    spellTimer.Start();
                }
                else
                    RemoveSpell(true, true);
            }
        }

        public void InstantCast(CreatureBase castingCreature, CreatureBase targetCreatureBase, SpellIcon _spellIcon, int castLevel)
        {
            //If its a creature custom cast, replace the targets ID
            if (choosenTarget != null)
                targetCreatureBase = choosenTarget;

            if (InitializeInstantCast(castingCreature, targetCreatureBase, _spellIcon, castLevel, true) == false)
                return;

            if (spellIcon.Skill == "Holy")
                minutesLeft = 1;

            BaseDotDamage = getBaseBySkill(spellIcon.Skill);
            ticksLeft = getTicksByBySkill(spellIcon.Skill);

            int DotAmount = BaseDotDamage * ticksLeft;

            if (spellIcon.Skill != "Holy")
            {
                DotAmount = SkillManager.AdjustForCombat(CastingCreatureLevel, DotAmount, CastingCreatureInt);
                DotAmount = TargetCreatureBase.CalculateGetSpellDamagePerResists(DotAmount, spellIcon.Skill);
            }
            else
                DotAmount = SkillManager.AdjustForCombat(CastingCreatureLevel, DotAmount, CastingCreatureWis);

            CalcDotDamage = DotAmount / ticksLeft;

            foreach (MapItem mapitem in TargetCreatureBase.currentMapItem.mapItemsWithin8)
            {
                foreach (CreatureBase creaturebase in mapitem.CreaturesBases)
                {
                    if (creaturebase is Character)
                    {
                        Character character = (Character)creaturebase;
                        if (spellIcon.Skill == "Fire" || spellIcon.Skill == "Mentality")
                            character.PlaySound("FireBolt", TargetCreatureBase.MapX, TargetCreatureBase.MapY);
                        else if (spellIcon.Skill == "Unholy" || spellIcon.Skill == "Ice")
                            character.PlaySound("Necrosis", TargetCreatureBase.MapX, TargetCreatureBase.MapY);
                        else if (spellIcon.Skill == "Holy")
                            character.PlaySound("Heal", TargetCreatureBase.MapX, TargetCreatureBase.MapY);

                        character.AddCreatureBase(TargetCreatureBase);
                    }
                }
            }

            TargetCreatureBase.buffManager.UpdateBuffs();

            spellTimer.Start();

        }
    }
}
